import 'moment/locale/zh-cn'

import Vue from 'vue'
import moment from 'moment'

const shortformat = (() => {
  var day, hour, initialize, minute, week

  minute = 6e4
  hour = 36e5
  day = 864e5
  week = 6048e5

  initialize = function (moment) {
    var shortFormat
    shortFormat = function (withoutPreOrSuffix, now) {
      var diff, num, result, unit
      now = now || moment()
      diff = Math.abs(this.diff(now))
      unit = null
      num = null

      if (diff < minute) {
        unit = 'seconds'
      } else if (diff < hour) {
        unit = 'minutes'
      } else if (diff < day) {
        unit = 'hours'
      } else if (diff < week) {
        unit = 'days'
      } else if (this.year() !== now.year()) {
        return this.format('YYYY年 MMM Do')
      } else {
        return this.format('MMM Do')
      }
      num = Math.max(1, moment.duration(diff)[unit]())

      const unitDisplay = {
        seconds: '秒',
        minutes: '分钟',
        hours: '小时',
        days: '天'
      }

      result = num + unitDisplay[unit]

      if (!withoutPreOrSuffix) {
        result = moment.localeData().pastFuture(this.diff(now), result)
      }

      return result
    }

    moment.fn.short = function (withoutPreOrSuffix, now) {
      return shortFormat.call(this, withoutPreOrSuffix, now)
    }
    return moment
  }

  return initialize
})()

shortformat(moment)

Vue.filter('shortformat', (d, format) => {
  return moment(d).short()
})

Vue.filter('moment', function () {
  const args = Array.prototype.slice.call(arguments)
  const input = args.shift()

  let date

  if (Array.isArray(input) && typeof input[0] === 'string') {
    // If input is array, assume we're being passed a format pattern to parse against.
    // Format pattern will accept an array of potential formats to parse against.
    // Date string should be at [0], format pattern(s) should be at [1]
    date = moment(input[0], input[1], true)
  } else {
    // Otherwise, throw the input at moment and see what happens...
    date = moment(input)
  }

  if (!date.isValid()) {
    // Log a warning if moment couldn't reconcile the input. Better than throwing an error?
    console.warn('Could not build a valid `moment` object from input.')
    return input
  }

  function parse () {
    const args = Array.prototype.slice.call(arguments)
    const method = args.shift()
    let obj = {}
    switch (method) {
      case 'add':

        // Mutates the original moment by adding time.
        // http://momentjs.com/docs/#/manipulating/add/

        var addends = args.shift()
          .split(',')
          .map(Function.prototype.call, String.prototype.trim)
        for (var n = 0; n < addends.length; n++) {
          var addend = addends[n].split(' ')
          obj[addend[1]] = addend[0]
        }
        date = date.add(obj)
        break

      case 'subtract':

        // Mutates the original moment by subtracting time.
        // http://momentjs.com/docs/#/manipulating/subtract/

        var subtrahends = args.shift()
          .split(',')
          .map(Function.prototype.call, String.prototype.trim)
        for (let n = 0; n < subtrahends.length; n++) {
          var subtrahend = subtrahends[n].split(' ')
          obj[subtrahend[1]] = subtrahend[0]
        }
        date = date.subtract(obj)
        break

      case 'from':

        // Display a moment in relative time, either from now or from a specified date.
        // http://momentjs.com/docs/#/displaying/fromnow/

        var from = 'now'
        if (args[0] === 'now') args.shift()

        if (moment(args[0]).isValid()) {
          // If valid, assume it is a date we want the output computed against.
          from = moment(args.shift())
        }

        let removeSuffix = false
        if (args[0] === true) {
          args.shift()
          removeSuffix = true
        }

        if (from !== 'now') {
          date = date.from(from, removeSuffix)
          break
        }

        date = date.fromNow(removeSuffix)
        break

      case 'calendar':

        // Formats a date with different strings depending on how close to a certain date (today by default) the date is.
        // http://momentjs.com/docs/#/displaying/calendar-time/

        var referenceTime = moment()

        if (moment(args[0]).isValid()) {
          // If valid, assume it is a date we want the output computed against.
          referenceTime = moment(args.shift())
        }

        date = date.calendar(referenceTime)
        break

      default:
        // Format
        // Formats a date by taking a string of tokens and replacing them with their corresponding values.
        // http://momentjs.com/docs/#/displaying/format/

        var format = method
        date = date.format(format)
    }

    if (args.length) parse.apply(parse, args)
  }

  parse.apply(parse, args)

  return date
})

Vue.filter('duration', (d, format, opts) => {
  if (opts) {
    return moment.duration(d).format(format, opts)
  }

  return moment.duration(d).format(format)
})

export default (ctx, inject) => {
  inject('moment', moment)
}
